﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Crank.Core
{
    public class LinkTableModelTransformer : IModelTransformer
    {
        #region Blackboard Variables

        private static readonly IProperty<NounSpace> Nouns = Blackboard.Create<NounSpace>("Nouns");

        #endregion

        #region IModelTransformer Members

        public void ApplyTransform(DataModel target)
        {
            IList<LinkDef> ManyManyLinks = new List<LinkDef>();
            foreach (LinkDef link in target.Links)
                if (link.Type == "<>")
                    ManyManyLinks.Add(link);

            foreach (LinkDef link in ManyManyLinks)
            {
                target.Links.Remove(link);
                HandleManyManyLink(target, link);
            }
        }

        #endregion

        private void HandleManyManyLink(DataModel model, LinkDef link)
        {
            var tableName = GetManyManyLinkTableName(link);
            var linkTable = model.GetEntityByName(tableName);
            var hasKeys = linkTable.Keys.Count(a=>true) > 0;

            model.Links.Add( CreateManyToOneLink(linkTable, link.LHS, !hasKeys) );
            model.Links.Add( CreateManyToOneLink(linkTable, link.RHS, !hasKeys) );            
        }

        private LinkDef CreateManyToOneLink(EntityDef lhs, EntityDef rhs, bool isKey)
        {
            LinkDef link = new LinkDef("=>");
            link.LHS = lhs;
            link.RHS = rhs;
            var Keys = rhs.Keys;

            AttributeDef att = new AttributeDef();
            att.IsKey = isKey;
            att.IsRequired = true;
            link.Detail = att;
            return link;
        }


        private string GetManyManyLinkTableName(LinkDef link)
        {
            if (link.Detail.Name != "_")
                return link.Detail.Name;
            return Nouns.Value.SingleOf(link.LHS.Name) +
                Nouns.Value.PluralOf(link.RHS.Name);
        }
    }
}
